<script setup>
import { computed, nextTick, onMounted, onUnmounted, reactive, ref, watch } from "vue";
import { ElLoading, ElMessage, ElMessageBox } from "element-plus";
import { Close, Minus, Moon, Setting, Sunny, WarningFilled } from "@element-plus/icons-vue";

import Info from "./views/info/Index.vue";
import Measure from "./views/measure/Index.vue";
import Statistic from "./views/statistic/Index.vue";
import Inspect from "./views/inspect/Index.vue";
import Times from "./views/times/Index.vue";
import SerialComponent from "./views/serials/Index.vue";

import { useInfoStoreHook } from "./store/modules/info";
import { useProcessStoreHook } from "./store/modules/process";
import { useDetectionStoreHook } from "./store/modules/detection";
import { useSerialsStoreHook } from "./store/modules/serials";

import iconDarkImage from "./assets/iconDark.svg";
import iconLightImage from "./assets/iconLight.svg";

const userInfo = useInfoStoreHook();
const process = useProcessStoreHook();
const detection = useDetectionStoreHook();
const serials = useSerialsStoreHook();
const selectPage = ref("info");

function close() {
  ElMessageBox.confirm("你确定要退出软件吗？", "提示", {
    confirmButtonText: "确 定",
    cancelButtonText: "取 消",
    type: "warning"
  })
    .then(() => window.api.close())
    .catch(() => {});
}

function mini() {
  window.api.mini();
}

function updateNow() {
  window.api.updateNow();
}

const settingPageVisible = ref(false);
const winSizeSelection = ref("normal");

function toSetting() {
  settingPageVisible.value = true;
}

async function winSizeChange(selection) {
  await window.api.resize(selection);
  await window.api.setStore("screenSize", selection);
}

// 是否开机自启动
const autoOpen = ref(true);
async function autoOpenChange(val) {
  await window.api.setAutoOpen(val);
}
const newVersion = ref("");
const hasNewVersion = ref(false);
const newVersionDownloaded = ref(false);
const downloadInfo = reactive({
  total: 0.0,
  delta: 0.0,
  transferred: 0.0,
  percent: 0.0,
  mbPerSecond: 0.0
});

async function autoCheckUpdate() {
  await window.api.checkUpdate();
  setTimeout(async () => {
    await autoCheckUpdate();
  }, 30 * 60 * 1000);
}

const tipsCheckUpdate = ref(false);

let fullLoading = null;

async function toCheckUpdate() {
  fullLoading = ElLoading.service();
  tipsCheckUpdate.value = true;
  await window.api.checkUpdate();
  setTimeout(() => {
    console.log("closed: ", fullLoading.closed);
    if (fullLoading && !fullLoading.closed?.value) {
      fullLoading.close();
      ElMessage.error("检查更新失败，请稍后重试！");
    }
  }, 10 * 1000);
}

const serialSettingVisible = ref(false);

function toOpenSerial() {
  serialSettingVisible.value = true;
}

// 自动更新
const updateVisible = ref(false);
const timeCounter = ref(10);
let timer;

watch(updateVisible, (val) => {
  if (val) {
    timer = setInterval(() => {
      timeCounter.value--;
      if (timeCounter.value <= 0) {
        clearInterval(timer);
        window.api.updateNow();
      }
    }, 1000);
  } else {
    if (timer) {
      clearInterval(timer);
      nextTick(() => (timeCounter.value = 10));
    }
  }
});

function startUpdateNow() {
  window.api.updateNow();
}

onMounted(async () => {
  const screenSize = await window.api.getStore("screenSize");
  if (screenSize) {
    await window.api.resize(screenSize);
    winSizeSelection.value = screenSize;
  }
  const storeAutoOpen = await window.api.getStore("autoOpen");
  if (storeAutoOpen !== undefined) autoOpen.value = storeAutoOpen;
  // 启用自动上报数据功能
  await window.api.autoPostDetection(true);
  // 软件更新异常的信息
  await window.api.updateErrListener((err) => {
    if (fullLoading) {
      fullLoading.close();
      ElMessage.error("网络异常，请稍后重试！");
      window.api.log(err);
    }
    tipsCheckUpdate.value = false;
  });
  // 监听是否有新版本
  await window.api.hasNewVersionListener((hasNew, info) => {
    // 手动检测更新时为用户提供信息提示
    if (tipsCheckUpdate.value) {
      fullLoading.close();
      if (hasNew) {
        ElMessage({
          type: "success",
          message: `检测到新版本v${info.version}，开始下载安装包`
        });
      } else {
        ElMessage({
          type: "success",
          message: "当前已是最新版本了！"
        });
      }
      tipsCheckUpdate.value = false;
    }
    newVersion.value = info.version;
    hasNewVersion.value = hasNew;
  });
  // 监听是否完成新版本安装包下载
  await window.api.downloadedListener(() => {
    newVersionDownloaded.value = true;
    updateVisible.value = true;
  });
  // 监听更新进度
  await window.api.downloadPercentListener((info) => {
    downloadInfo.percent = info.percent.toFixed(1);
    downloadInfo.transferred = (info.transferred / 1024 / 1024).toFixed(1);
    downloadInfo.total = (info.total / 1024 / 1024).toFixed(1);
    downloadInfo.mbPerSecond = (info.bytesPerSecond / 1024 / 1024).toFixed(1);
  });
  // 启动定时检测更新
  await autoCheckUpdate();
  // 初始化串口
  serials.serialInit();
});
onUnmounted(async () => {
  await window.api.autoPostDetection(false);
});

const currentWorkTypeName = computed(() => {
  for (let i = 0; i < userInfo.workTypeOptions.length; i++) {
    const opt = userInfo.workTypeOptions[i];
    if (opt.value === userInfo.work_type) {
      return opt.label;
    }
  }
  return null;
});

// 网络是否正常
const networkStatus = ref(navigator.onLine);
window.addEventListener("online", () => {
  networkStatus.value = true;
});
window.addEventListener("offline", () => {
  networkStatus.value = false;
});

function showWifiTips() {
  if (networkStatus.value) {
    ElMessage.success("当前网络正常");
  } else {
    ElMessageBox.confirm("一体机未接入网络，请检查网线或WIFI是否正常", "网络异常", {
      type: "error",
      showCancelButton: false
    });
  }
}

// 检查串口设备是否正常连接
const serialIconColor = ref("var(--el-color-error)");
const serialErr = computed(() => {
  for (let i = 0; i < serials.list.length; i++) {
    const ser = serials.list[i];
    if (ser.opened || !ser.iconName) continue;
    return {
      iconName: ser.iconName,
      toOpen: () => {
        serialIconColor.value = "var(--el-color-warning)";
        setTimeout(() => {
          serialIconColor.value = "var(--el-color-error)";
        }, 500);
        serials.openSerial(i);
      }
    };
  }
  return null;
});

// 主题切换
const isDark = ref();
onMounted(async () => {
  isDark.value = (await window.api.getStore("isDark")) ?? true;
});
watch(isDark, async (val) => {
  const htmlEl = document.querySelector("html");
  if (val === false) {
    htmlEl.classList.remove("dark");
  } else {
    htmlEl.classList.add("dark");
  }
  await window.api.setStore("isDark", val);
});
</script>

<template>
  <div style="width: 100%; height: 100%">
    <div class="title">
      <div class="system-info">
        <div style="display: flex">
          <img class="icon" :src="isDark === false ? iconLightImage : iconDarkImage" alt="" />
          <div class="client-name">量仪采集客户端</div>
          <span v-if="process.processName" class="process">{{ process.processName }}</span>
          <span class="work-type">{{ currentWorkTypeName }}</span>
        </div>
        <div class="welcome">
          {{
            userInfo.isLogin
              ? userInfo.realname + `, 你好！ ${userInfo.userTips}`
              : "请先输入工号或刷卡进行登录"
          }}
        </div>
      </div>
      <div class="overall-btn">
        <div v-if="serialErr" class="connect-box">
          <!-- <svg-icon icon-name="icon-card-connect" color="#f00" /> -->
          <svg-icon
            :icon-name="serialErr.iconName"
            :color="serialIconColor"
            @click="serialErr.toOpen"
          />
        </div>
        <div class="connect-box" @click="showWifiTips">
          <svg-icon
            :icon-name="networkStatus ? 'icon-wifi-on' : 'icon-wifi-off'"
            :color="networkStatus ? 'var(--el-color-primary)' : 'var(--el-color-danger)'"
          ></svg-icon>
        </div>
        <el-button text @click="toSetting">
          <el-icon>
            <el-badge :is-dot="hasNewVersion && newVersionDownloaded">
              <Setting />
            </el-badge>
          </el-icon>
        </el-button>
        <el-button text :icon="Minus" @click="mini" />
        <el-button type="danger" text :icon="Close" @click="close" />
      </div>
    </div>
    <el-tabs v-model="selectPage" class="content" type="card">
      <el-tab-pane label="基本信息" name="info" class="child-page">
        <info />
      </el-tab-pane>
      <el-tab-pane label="检测数据" name="measure">
        <measure />
      </el-tab-pane>
      <el-tab-pane v-if="detection.inspectFields.length > 0" label="零部件送检记录" name="inspect">
        <inspect />
      </el-tab-pane>
      <el-tab-pane label="点检记录" name="statistic">
        <statistic />
      </el-tab-pane>
      <el-tab-pane label="检频统计" name="times">
        <times />
      </el-tab-pane>
      <!--      <el-tab-pane label="串口设置" name="123">-->
      <!--        <serials />-->
      <!--      </el-tab-pane>-->
    </el-tabs>
    <el-dialog v-model="settingPageVisible" title="系统设置" top="7vh">
      <el-form size="large" label-width="78px" style="margin: 0 12px">
        <el-form-item label="主题">
          <el-switch
            v-model="isDark"
            width="56px"
            inline-prompt
            :active-action-icon="Moon"
            :inactive-action-icon="Sunny"
            style="
              --el-switch-on-color: var(--el-border-color);
              --el-switch-off-color: var(--el-border-color);
            "
          />
        </el-form-item>
        <el-form-item label="自启动">
          <el-switch v-model="autoOpen" width="56px" @change="autoOpenChange" />
        </el-form-item>
        <el-form-item label="分辨率">
          <el-select v-model="winSizeSelection" style="width: 100%" @change="winSizeChange">
            <el-option label="常规 (800 × 480)" value="normal" />
            <el-option label="中屏 (1200 × 720)" value="middle" />
            <el-option label="最大化" value="max" />
            <el-option label="全屏" value="full" />
          </el-select>
        </el-form-item>
        <el-form-item label="设备通讯">
          <el-button plain style="width: 100%" @click="toOpenSerial">点 击 设 置</el-button>
        </el-form-item>
        <el-form-item label="软件更新">
          <el-badge v-if="hasNewVersion && newVersionDownloaded" is-dot style="width: 100%">
            <el-button type="primary" style="width: 100%" @click="updateNow">
              新版本v{{ newVersion }} 点击开始更新</el-button
            >
          </el-badge>
          <span v-else-if="hasNewVersion" style="width: 100%; text-align: center"
            >新版本安装包下载中...</span
          >
          <el-button v-else plain style="width: 100%" @click="toCheckUpdate">
            检 查 更 新</el-button
          >
        </el-form-item>
        <el-progress
          v-if="hasNewVersion && !newVersionDownloaded"
          :text-inside="true"
          striped
          striped-flow
          :duration="10"
          :stroke-width="16"
          :percentage="downloadInfo.percent"
        />
        <p v-if="hasNewVersion && !newVersionDownloaded" class="download-info">
          {{ downloadInfo.transferred }}/{{ downloadInfo.total }}MB ({{
            downloadInfo.mbPerSecond
          }}MB/s)
        </p>
      </el-form>
    </el-dialog>
    <el-dialog v-model="serialSettingVisible" fullscreen append-to-body>
      <SerialComponent />
    </el-dialog>

    <el-dialog v-model="updateVisible" align-center>
      <template #header>
        <div style="font-size: 18px">提示</div>
      </template>
      <template #default>
        <div class="msg-box-content">
          <el-icon class="icon-box" :size="26"><WarningFilled /></el-icon>
          <p style="margin-left: 12px">
            发现新版本，是否进行更新？
            <span>{{ timeCounter }}秒</span> 后软件将自动进行更新
          </p>
        </div>
      </template>
      <template #footer>
        <div class="btn-group">
          <el-button @click="updateVisible = false">稍后再说</el-button>
          <el-button type="primary" @click="startUpdateNow">立即更新</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<style lang="scss">
html,
body,
#app {
  margin: 0;
  padding: 0;
  height: 100%;
  width: 100%;
}
body {
  .el-err-msg {
    p {
      color: #f56c6c;
      font-size: 24px;
      line-height: 48px;
      margin-left: 96px;
    }
    .el-message-box__content {
      margin-top: 48px;
      margin-bottom: 48px;
    }
    .el-message-box__title > span {
      color: #f56c6c;
      font-size: 42px;
      line-height: 52px;
      margin: 0 0 0 12px;
    }
    .el-message-box__status {
      font-size: 110px !important;
    }
    .el-button {
      height: 56px !important;
      width: 120px !important;
      margin: 0 12px 12px 0;
    }
  }
}
.update-form {
  width: 100%;
  height: 100%;
  .title {
    height: 48px;
    width: 100%;
    display: flex;
    .el-button {
      margin-left: auto;
      width: 64px;
      font-size: 24px !important;
    }
  }
  .update-content {
    height: calc(100% - 48px);
    width: 100%;
    display: flex;
    flex-direction: column;
    .update-tips {
      margin: 12px;
      text-align: center;
    }
    .update-progress {
      margin: 12px 24px 12px 24px;
    }
  }
}
.system-info {
  line-height: 48px;
  width: calc(100% - 4 * 64px);
  font-size: 13px;
  color: #888888;
  display: flex;
  justify-content: space-between;
  align-items: center;
  cursor: default;
  user-select: none;
  -webkit-app-region: drag;
  .icon {
    margin: 0 12px 0 16px;
  }
  .client-name {
    font-size: 16px;
    color: var(--el-text-color-primary);
    margin-right: 12px;
  }
  .welcome {
    margin-right: 12px;
  }
  .process {
    color: #409eff;
    font-size: 14px;
  }
  .work-type {
    color: #409eff;
    font-size: 14px;
    margin-left: 12px;
  }
}
.title {
  margin: 0;
  display: flex;
  justify-content: space-between;
}
.content {
  height: calc(100% - 48px);
}
.child-page {
  margin: 8px 24px 0 24px;
}
.overall-btn {
  display: flex;
  justify-content: center;
  .connect-box {
    display: inline-flex;
    justify-content: center;
    align-items: center;
    line-height: 1;
    box-sizing: border-box;
    height: 48px;
    width: 32px;
  }
  .el-button {
    padding: 0 !important;
    margin: 0 !important;
    width: 64px !important;
    height: 48px !important;
    font-size: 24px !important;
  }
}
.download-info {
  width: 100%;
  text-align: right;
  font-size: 12px;
  color: #666666;
  cursor: default;
  user-select: none;
  margin: 0;
}

.msg-box-content {
  display: flex;
  // flex-direction: row;
  // justify-content: center;
  line-height: 24px;
  .icon-box {
    color: var(--el-color-warning);
  }
  p {
    padding: 0;
    margin: 0;
    font-size: 16px;
    span {
      font-size: 18px;
      color: var(--el-color-primary);
    }
  }
}

.el-button {
  font-size: 16px !important;
  height: 48px !important;
  width: 90px;
}
.el-input {
  height: 48px;
  .el-input__inner {
    font-size: 16px;
  }
}
.el-tabs__header {
  height: 48px !important;
}
.el-tabs__item {
  height: 48px !important;
  min-width: 128px;
  font-size: 16px !important;
}
.el-tabs__content {
  height: calc(100% - 48px - 8px - 10px);
}
.el-tab-pane {
  height: calc(100%);
}
.el-form-item__label {
  font-size: 16px !important;
  height: 48px !important;
  line-height: 48px !important;
}
.el-badge__content.is-dot {
  height: 12px !important;
  width: 12px !important;
}
.el-badge__content.is-fixed.is-dot {
  right: 6px !important;
}
.el-dialog__headerbtn {
  width: 64px !important;
  font-size: 24px !important;
}
</style>
